<?php

namespace App\Console\Commands\Mybank;

use App\Exceptions\BaseException;
use App\Kuafu\Mybank\Model\MybankBalanceUnfreezeRecordModel;
use App\Kuafu\Mybank\Model\MybankEntryModel;
use App\Kuafu\Mybank\Model\MybankOrderWithholdRecordModel;
use App\Kuafu\Mybank\Model\MybankVostroBillModel;
use App\Kuafu\Mybank\Service\MybankOrderWithholdV2Service;
use App\Library\SnowFlake\SnowFlake;
use App\Remote\Mybank\MybankAccountRemote;
use App\Remote\Mybank\Remote;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;

class UnfreezeMerchantBalanceCommand extends Command
{
    protected $signature = 'mybank:unfreezeMerchantBalance';

    protected $description = '网商账户余额解冻';

    /**
     * @throws GuzzleException
     * @throws BaseException
     */
    public function handle()
    {
        Artisan::call('mybank:query-account-balance');

        // 判断是否有存在未处理的分账原始数据
        $remainList = MybankVostroBillModel::query()
                                            ->where('type', MybankVostroBillModel::DEFAULT_TYPE)
                                            ->where('flagMark', MybankVostroBillModel::DEFAULT_FLAG_MARK)
                                            ->where('payerBankId', '!=', '310290000013') // 亚太财产保险有限公司
                                            ->where('payerBankId', '!=', 'ALIPW3CN') // 支付宝（中国）网络技术有限公司
                                            ->get();


//        dump($remainList);
        if (count($remainList)) {
            Log::channel('mybank')->error('余额解冻失败', [
                'msg'          => '暂不能余额解冻, 当前还剩余' . count($remainList) . '笔原始订单未处理',
                'fsNotifyUids' => [
                    '3fgc8798'
                ]
            ]);
            return;
        }

        $list = MybankEntryModel::query()
                                ->select(['merchantId', 'status', 'id'])
                                ->where('status', MybankEntryModel::STATUS_3)
                                ->with([
                                    'shopBindRel'
                                ])
                                ->get()
                                ->filter(function ($item) {
                                    if (count($item->shopBindRel) > 0) {
                                        return true;
                                    }
                                    return false;
                                })
                                ->values();

        foreach ($list as $merchantInfo) {

            $withholdV2Service = (new MybankOrderWithholdV2Service(0, $merchantInfo->merchantId));

            $balanceFreeze = $withholdV2Service->getBalanceFreeze();

            if ($balanceFreeze == 0) {
                continue;
            }

            /*** 余额解冻记录 ***/
            $outTradeNo                = SnowFlake::nextIdCache();
            $balanceModel              = new MybankBalanceUnfreezeRecordModel();
            $balanceModel->merchantId  = $merchantInfo->merchantId;
            $balanceModel->withholdId  = 0;
            $balanceModel->outTradeNo  = $outTradeNo;
            $balanceModel->accountType = 'BALANCE';
            $balanceModel->amount      = $balanceFreeze;
            $balanceModel->currency    = 'CNY';
            $balanceModel->save();

            // 余额解冻
            $unfreezeApplyResult = MybankAccountRemote::unfreezeApply($merchantInfo->merchantId, $balanceFreeze,
                $outTradeNo);

            if (Remote::checkBodySuccess($unfreezeApplyResult)) {
                $balanceModel->status         = MybankOrderWithholdRecordModel::WITHHOLD_STATUS_SUBMIT;
                $balanceModel->operateNo      = $unfreezeApplyResult['OperateNo'];
                $balanceModel->submitDateTime = time();
                $balanceModel->save();
            } else {
                // 异常报错
                throw new \Exception(0, '解冻余额异常');
            }
        }

        Log::channel('mybank')->notice('余额解冻成功', [
            'msg' => '当日分账、余额解冻正常',
        ]);
        return;

    }
}
